package com.cosmoplat.xikai.business.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cosmoplat.xikai.business.config.mes.MesUrl;
import com.cosmoplat.xikai.business.config.producLine.LocationConfig;
import com.cosmoplat.xikai.business.domain.BaseDeliveryInfo;
import com.cosmoplat.xikai.business.domain.BaseDispatchTask;
import com.cosmoplat.xikai.business.domain.BaseMesNotUpload;
import com.cosmoplat.xikai.business.domain.BaseWorkOrder;
import com.cosmoplat.xikai.business.domain.dto.mes.ProductionPlanByMesDTO;
import com.cosmoplat.xikai.business.domain.dto.productPlan.*;
import com.cosmoplat.xikai.business.domain.mes.req.MesMaterialDistributionRequest;
import com.cosmoplat.xikai.business.domain.mes.req.MesRequest;
import com.cosmoplat.xikai.business.domain.mes.req.MesStartWorkRequest;
import com.cosmoplat.xikai.business.domain.mes.result.MesResult;
import com.cosmoplat.xikai.business.domain.vo.MaterialQty;
import com.cosmoplat.xikai.business.domain.vo.ProductTaskVo;
import com.cosmoplat.xikai.business.domain.vo.orderTemplate.ProductPlanTemplate;
import com.cosmoplat.xikai.business.enums.DeviceParamsEnum;
import com.cosmoplat.xikai.business.enums.DeviceRunStatusEnum;
import com.cosmoplat.xikai.business.enums.MaterialEnum;
import com.cosmoplat.xikai.business.enums.ProductEnum;
import com.cosmoplat.xikai.business.service.*;
import com.cosmoplat.xikai.common.core.domain.AjaxResult;
import com.cosmoplat.xikai.common.enums.DelFlagEnum;
import com.cosmoplat.xikai.common.enums.business.MesTaskStatusEnum;
import com.cosmoplat.xikai.common.enums.business.TaskPlanStatusEnum;
import com.cosmoplat.xikai.common.exception.ServiceException;
import com.cosmoplat.xikai.common.utils.SecurityUtils;
import com.cosmoplat.xikai.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName ProductionPlanServiceImpl
 * @Description 生产计划服务实现类
 * @Author wdf
 * @Date 2025/1/7
 */
@Slf4j
@Service
public class ProductionPlanServiceImpl implements ProductionPlanService {


    @Autowired
    private BaseDispatchTaskService dispatchTaskService;

    @Autowired
    private BaseDeliveryInfoService deliveryInfoService;

    @Autowired
    private BaseWorkOrderService workOrderService;

    @Autowired
    private MesCallService mesCallService;

    @Autowired
    private MesRequestService mesRequestService;

    @Autowired
    private MesUrl mesUrl;
    @Autowired
    private DeviceCallService deviceCallService;
    @Value("${device.code}")
    private String deviceCode;


    @Autowired
    private LocationConfig locationConfig;
    @Autowired
    private BaseMesNotUploadService baseMesNotUploadService;
    @Autowired
    private BaseWorkOrderService baseWorkOrderService;
    @Autowired
    private BaseDispatchTaskService baseDispatchTaskService;
    @Autowired
    private BaseDeliveryInfoService baseDeliveryInfoService;

    @Override
    public List<ProductTaskVo> queryForPage(ProductPlanQueryDTO queryDTO) {
        QueryWrapper<BaseDispatchTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(BaseDispatchTask::getIsDelete, DelFlagEnum.NORMAL.getCode())
                .orderByDesc(BaseDispatchTask::getUpdateTime)
                .orderByAsc(BaseDispatchTask::getWorkOrderNo)
                .orderByAsc(BaseDispatchTask::getTaskNo);
        if (StringUtils.isNotEmpty(queryDTO.getWorkOrderNo())) {
            queryWrapper.lambda().like(BaseDispatchTask::getWorkOrderNo, queryDTO.getWorkOrderNo());
        }
        if (StringUtils.isNotEmpty(queryDTO.getMaterialCode())) {
            queryWrapper.lambda().like(BaseDispatchTask::getMaterialCode, queryDTO.getMaterialCode());
        }
        if (StringUtils.isNotEmpty(queryDTO.getMaterialName())) {
            queryWrapper.lambda().like(BaseDispatchTask::getMaterialName, queryDTO.getMaterialName());
        }
        if (queryDTO.getTaskPlanStatus() != null) {
            queryWrapper.lambda().eq(BaseDispatchTask::getTaskPlanStatus, queryDTO.getTaskPlanStatus());
        }
        if (queryDTO.getPlanStartTime() != null && queryDTO.getPlanEndTime() != null) {
            queryWrapper.lambda().between(BaseDispatchTask::getPlanStartTime, queryDTO.getPlanStartTime(), queryDTO.getPlanEndTime());
        }
        List<ProductTaskVo> list = dispatchTaskService.queryProductionPlanList(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        List<String> orderIdList = list.stream().map(ProductTaskVo::getOrderId).collect(Collectors.toList());
        QueryWrapper<BaseWorkOrder> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.lambda().in(BaseWorkOrder::getOrderId, orderIdList);
        List<BaseWorkOrder> workOrders = workOrderService.list(queryWrapper2);
        if (CollectionUtils.isEmpty(workOrders)) {
            return list;
        }
        Map<String, BaseWorkOrder> map = workOrders.stream().collect(Collectors.toMap(BaseWorkOrder::getOrderId, x -> x));
        for (ProductTaskVo productTaskVo : list) {
            if (map.containsKey(productTaskVo.getOrderId())) {
                BaseWorkOrder baseWorkOrder = map.get(productTaskVo.getOrderId());
                productTaskVo.setProjectCode(baseWorkOrder.getProjectCode());
                productTaskVo.setProjectName(baseWorkOrder.getProjectName());
                productTaskVo.setMaterialModel(baseWorkOrder.getMaterialModel());
            }
        }
        return list;
    }

    @Transactional
    @Override
    public boolean taskDeliver(TaskDeliverDTO taskDeliverDTO) {
        BaseDispatchTask baseDispatchTask = dispatchTaskService.getById(taskDeliverDTO.getId());
        if (baseDispatchTask == null) {
            throw new ServiceException("任务不存在:" + taskDeliverDTO.getTaskNo());
        }
        if (taskDeliverDTO.getTaskPlanStatus().equals(TaskPlanStatusEnum.DOING.getCode())&&TaskPlanStatusEnum.DOING.getCode().equals(baseDispatchTask.getTaskPlanStatus())) {
            throw new ServiceException("任务已下发:" + taskDeliverDTO.getTaskNo());
        }
        // 开工
        if (TaskPlanStatusEnum.DOING.getCode().equals(taskDeliverDTO.getTaskPlanStatus())) {
            // 检查有已经进行中的任务
            BaseDispatchTask doingTask = dispatchTaskService.getDoingTask();
            if (doingTask != null) {
                throw new ServiceException("有任务正在执行中:" + doingTask.getTaskNo());
            }
            baseDispatchTask.setTaskPlanStatus(TaskPlanStatusEnum.DOING.getCode());
            baseDispatchTask.setTaskStartTime(new Date());
            baseDispatchTask.setIssuer(SecurityUtils.getUsername());

            // 开工通知mes
            MesStartWorkRequest startWorkRequest = new MesStartWorkRequest();
            startWorkRequest.setTaskID(baseDispatchTask.getTaskId());
            startWorkRequest.setCreateTime(new Date());
            startWorkRequest.setOperation("1");
            boolean startedWorkResult = startWork(startWorkRequest,baseDispatchTask.getId());
            //判断mes是否调通
            if (!startedWorkResult) {
                //判断调用本地mes时是否师傅已经准备叫料
                if (taskDeliverDTO.getDistributionStatus()!=null&&taskDeliverDTO.getDistributionStatus()==1) {
//                    //   对接数采的开工逻辑
//                    //todo:现场调用记得开启
                    if (!deviceCallService.runStatusSendCommand(deviceCode,baseDispatchTask.getMaterialModel(),baseDispatchTask.getDispatchQty().stripTrailingZeros().toPlainString())) {
                        return false;
                    }
                }else {
                    return false;
                }
            }else {
//                //   对接数采的开工逻辑
//                //todo:现场调用记得开启
                if (!deviceCallService.runStatusSendCommand(deviceCode,baseDispatchTask.getMaterialModel(),baseDispatchTask.getDispatchQty().stripTrailingZeros().toPlainString())) {
                    log.warn("下发设备开工失败");
                    throw new ServiceException("下发设备开工失败");
                }
                // 通知mes叫料
                log.info("开工 - 通知mes叫料");
                callMaterial(baseDispatchTask, MesMaterialDistributionRequest.DeliveryTypeEnum.DISTRIBUTION);
                // 通知mes送料
                log.info("开工 - 通知mes送料");
                callMaterial(baseDispatchTask, MesMaterialDistributionRequest.DeliveryTypeEnum.DELIVERY);
            }

//        } else if (TaskPlanStatusEnum.PAUSE.getCode().equals(baseDispatchTask.getTaskPlanStatus())) {
        } else if (TaskPlanStatusEnum.PAUSE.getCode().equals(taskDeliverDTO.getTaskPlanStatus())) {
            // 检查任务是否处于开工状态
            if (!TaskPlanStatusEnum.DOING.getCode().equals(baseDispatchTask.getTaskPlanStatus())) {
                throw new ServiceException("任务未开工:" + baseDispatchTask.getTaskNo());
            }
            baseDispatchTask.setTaskPlanStatus(TaskPlanStatusEnum.PAUSE.getCode());

            //   对接数采的暂停逻辑逻辑
            if (!deviceCallService.sendCommand(deviceCode, DeviceParamsEnum.RUN_STATE.getName(), DeviceRunStatusEnum.SUSPEND_PRODUCTION.getCode())) {
                log.warn("下发设备暂停失败");
                throw new ServiceException("下发设备暂停失败");
            }

            // 取消开工通知mes
            MesStartWorkRequest startWorkRequest = new MesStartWorkRequest();
            startWorkRequest.setTaskID(baseDispatchTask.getTaskId());
            startWorkRequest.setOperation("0");
            startWork(startWorkRequest,baseDispatchTask.getId());
        } else if (TaskPlanStatusEnum.RESTART.getCode().equals(taskDeliverDTO.getTaskPlanStatus())) {
            // 检查有已经进行中的任务
            BaseDispatchTask doingTask = dispatchTaskService.getDoingTask();
            if (doingTask != null) {
                throw new ServiceException("有任务正在执行中:" + doingTask.getTaskNo());
            }
            baseDispatchTask.setTaskPlanStatus(TaskPlanStatusEnum.DOING.getCode());

            // 对接数采的重新生产逻辑逻辑
            if (!deviceCallService.sendCommand(deviceCode, DeviceParamsEnum.RUN_STATE.getName(), DeviceRunStatusEnum.REPRODUCTION.getCode())) {
                log.warn("下发设备开工失败");
                throw new ServiceException("下发设备开工失败");
            }
            // 开工通知mes
            MesStartWorkRequest startWorkRequest = new MesStartWorkRequest();
            startWorkRequest.setTaskID(baseDispatchTask.getTaskId());
            startWorkRequest.setCreateTime(new Date());
            startWorkRequest.setOperation("1");
            startWork(startWorkRequest,baseDispatchTask.getId());

        }
        return dispatchTaskService.updateById(baseDispatchTask);
    }

    /**
     * 通知mes叫料
     *
     * @param baseDispatchTask
     * @date 15:20 2025/1/10
     **/
    private void callMaterial(BaseDispatchTask baseDispatchTask, MesMaterialDistributionRequest.DeliveryTypeEnum distTypeEnum) {
        // 获取全部物料的详情
        List<BaseDeliveryInfo> baseDeliveryInfoList = deliveryInfoService.getListByTaskId(baseDispatchTask.getTaskId());

        for (BaseDeliveryInfo deliveryInfo : baseDeliveryInfoList) {
            // 获取全部物料的现有库存数量
            MaterialQty materialQty = new MaterialQty();
            String materialCodeValue = deviceCallService.getMaterialCodeValue(deviceCode, deliveryInfo.getMaterialCode());
            // 获取物料的库存数量 - 手动调整的库存
            if (MaterialEnum.inStockMaterial(deliveryInfo.getMaterialCode())) {
                materialCodeValue = deliveryInfo.getStockQty().toPlainString();
            }
            if (StringUtils.isEmpty(materialCodeValue)) {
                log.error("物料：{}, 获取的数量为空, 默认为0", deliveryInfo.getMaterialCode());
                materialCodeValue = "0";
            }
            materialQty.setMaterialCode(deliveryInfo.getMaterialCode());
            materialQty.setQty(new BigDecimal(materialCodeValue));
            log.info("当前物料的剩余数量 = {}", materialQty);

            MesMaterialDistributionRequest distribution = new MesMaterialDistributionRequest();
            distribution.setCode(baseDispatchTask.getTaskNo());
            distribution.setOrderID(baseDispatchTask.getWorkOrderNo());
            distribution.setTaskID(baseDispatchTask.getTaskId());
            distribution.setDeliveryType(distTypeEnum.getCode());
            // 需求数量 (生产的产品数量 * 单个产品所需要的物料数量) - 现有的库存数量
            BigDecimal needQty = deliveryInfo.getRequiredQty().multiply(baseDispatchTask.getDispatchQty());
            // 需要的数量 小于 现有的物料数量不叫料
            if (needQty.compareTo(materialQty.getQty()) <= 0) {
                log.info("物料：{}, 需要的数量: {} 小于 现有的物料数量: {} 不叫料", deliveryInfo.getMaterialCode(), needQty, materialQty.getQty());
                return;
            }
            distribution.setQuantity(needQty.subtract(materialQty.getQty()));

            distribution.setMaterial(deliveryInfo.getMaterialCode());
            distribution.setCreator(SecurityUtils.getLoginUser().getUser().getUserName());

            distribution.setEndLocation(locationConfig.getReceive());
            distribution.setCreateTime(new Date());
            distribution.setLastModifiedTime(new Date());
            // 工序传值  - 工序编码
            log.debug("工序: {}", baseDispatchTask.getProcessCode());
            distribution.setProcessStep(baseDispatchTask.getProcessCode());
            mesRequestService.materialDistribution(distribution);
        }

    }


    /**
     * 开工通知mes
     *
     * @param startWorkRequest
     */
    private boolean startWork(MesStartWorkRequest startWorkRequest,Long baseDispatchTaskId) {
        startWorkRequest.setOperator(SecurityUtils.getLoginUser().getUser().getUserName());
        startWorkRequest.setOperationTime(new Date());
        startWorkRequest.setLastModifiedTime(new Date());

        // 封装请求
        MesRequest mesRequest = new MesRequest();
        mesRequest.setUrl(mesUrl.getStartWork());
        mesRequest.setJson(JSON.toJSONString(startWorkRequest));
        String res ="";
        try {
            log.info("开工通知mes-请求参数: {}", mesRequest);
            res=mesRequestService.sendRequest(mesRequest);
        }catch (Exception e) {
            log.error("mes返回异常: {}", e);
            e.printStackTrace();
            //将未上报的数据进行保存未上报mes数据库
            BaseMesNotUpload baseMesNotUpload = baseMesNotUploadService.getOne(new LambdaQueryWrapper<BaseMesNotUpload>().eq(BaseMesNotUpload::getBaseDispatchTaskId, baseDispatchTaskId));
            if (baseMesNotUpload==null) {
                baseMesNotUploadService.save(new BaseMesNotUpload(baseDispatchTaskId,startWorkRequest.getOperation(), new Date()));
            }else {
                baseMesNotUpload.setBaseDispatchTaskStatus(startWorkRequest.getOperation());
                baseMesNotUpload.setUpdateTime(new Date());
                baseMesNotUploadService.updateById(baseMesNotUpload);
            }
            return false;
        }
        JSONObject jsonObject = JSONObject.parseObject(res);
        MesResult result = jsonObject.toJavaObject(MesResult.class);
        if (!result.isSuccess()) {
            log.error("mes返回异常：{}", result);
            /**
             * {
             * 	"code": 500,
             * 	"message": "系统提示：所选数据存在已开始派工任务",
             * 	"data": null
             * }
             */
            if (result.getMessage().contains("已开始派工任务")) {
                log.info("所选数据存在已开始派工任务");
                return true;
            }
            throw new ServiceException("mes返回异常:" + result.getMessage());
        }
        return true;
    }

    @Transactional
    @Override
    public String importPlan(List<ProductPlanTemplate> list, String operName) throws ParseException {
        if (CollectionUtils.isEmpty(list)) {
            return "导入数据为空";
        }

        // 订单id
        Map<String, ProductionPlanByMesDTO> productionPlanMap = new HashMap<>();
        // 任务id
        Map<String, BaseDispatchTask> dispatchTaskMap = new HashMap<>();

        for (ProductPlanTemplate template : list) {
            if (template == null) {
                throw new ServiceException("导入数据行为空");
            }
            // 同一个订单
            if (productionPlanMap.containsKey(template.getOrderID())) {
                ProductionPlanByMesDTO productionPlan = productionPlanMap.get(template.getOrderID());
                // 同一个任务
                if (dispatchTaskMap.containsKey(template.getTaskNo())) {
                    BaseDispatchTask dispatchTask = dispatchTaskMap.get(template.getTaskNo());
                    // 新的配送信息 (任务内部新增配送信息)
                    BaseDeliveryInfo deliveryInfo = template.copyToDeliveryInfo();
                    dispatchTask.getDeliveryInfo().add(deliveryInfo);
                } else {
                    // 新的任务
                    BaseDispatchTask dispatchTask = template.copyToDispatchTask();
                    // 新的配送信息
                    BaseDeliveryInfo deliveryInfo = template.copyToDeliveryInfo();

                    // 封装信息
                    dispatchTask.setDeliveryInfo(Arrays.asList(deliveryInfo));
                    productionPlan.setDispatchTask(Arrays.asList(dispatchTask));
                }

            } else {
                // 新的订单
                ProductionPlanByMesDTO productionPlan = template.copyToProductionPlan();
                // 新任务
                BaseDispatchTask dispatchTask = template.copyToDispatchTask();
                // 新的配送信息
                BaseDeliveryInfo deliveryInfo = template.copyToDeliveryInfo();

                // 封装信息
                dispatchTask.setDeliveryInfo(Arrays.asList(deliveryInfo));
                productionPlan.setDispatchTask(Arrays.asList(dispatchTask));
                dispatchTaskMap.put(template.getTaskId(), dispatchTask);
                productionPlanMap.put(template.getOrderID(), productionPlan);
            }
        }

        for (ProductionPlanByMesDTO planByMesDTO : productionPlanMap.values()) {
            planByMesDTO.setIsFileImport(true);
            mesCallService.productionPlan(planByMesDTO);
        }

        return "导入完成";
    }


    @Override
    public String save(ProductionPlanDTO productionPlanDTO) {
        BaseWorkOrder baseWorkOrder = new BaseWorkOrder();
        baseWorkOrder.setOrderId(productionPlanDTO.getOrderId());
        List<BaseWorkOrder> orderList = baseWorkOrderService.list(new LambdaQueryWrapper<BaseWorkOrder>().eq(BaseWorkOrder::getOrderId, productionPlanDTO.getOrderId()));
        //判断是否是唯一值
        if ((orderList.size()!=0&&productionPlanDTO.getId()==null)||(productionPlanDTO.getId()!=null&&orderList.size()>1)) {
            throw new ServiceException("派工单ID重复");
        }
        ArrayList<DispatchTaskDTO> dispatchTaskList = productionPlanDTO.getDispatchTask();
        for (DispatchTaskDTO dispatchTaskDTO : dispatchTaskList) {
            List<BaseDispatchTask> dispatchTaskNoList = dispatchTaskService.list(new LambdaQueryWrapper<BaseDispatchTask>().eq(BaseDispatchTask::getTaskNo, dispatchTaskDTO.getTaskNo()));
            if ((dispatchTaskNoList.size()!=0&&dispatchTaskDTO.getId()==null)||(dispatchTaskDTO.getId()!=null&&dispatchTaskNoList.size()>1)) {
                throw new ServiceException("任务号重复");
            }
            List<BaseDispatchTask> dispatchTaskIdList = dispatchTaskService.list(new LambdaQueryWrapper<BaseDispatchTask>().eq(BaseDispatchTask::getTaskId, dispatchTaskDTO.getTaskId()));
            if ((dispatchTaskIdList.size()!=0&&dispatchTaskDTO.getId()==null)||(dispatchTaskDTO.getId()!=null&&dispatchTaskIdList.size()>1)) {
                throw new ServiceException("任务ID重复");
            }
        }
        baseWorkOrder.setOrderNo(productionPlanDTO.getOrderNo());
        baseWorkOrder.setMaterialId(productionPlanDTO.getMaterialId());
        baseWorkOrder.setMaterialCode(productionPlanDTO.getMaterialCode());
        baseWorkOrder.setMaterialName(productionPlanDTO.getMaterialName());
        baseWorkOrder.setTaskStatus(0);
        baseWorkOrder.setIsDelete(false);
        if (productionPlanDTO.getId()==null) {
            baseWorkOrder.setCreateTime(new Date());
            baseWorkOrder.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
            baseWorkOrderService.save(baseWorkOrder);
        }else {
            baseWorkOrder.setUpdateTime(new Date());
            baseWorkOrder.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
            baseWorkOrder.setId(Long.valueOf(productionPlanDTO.getId()));
            baseWorkOrderService.updateById(baseWorkOrder);
        }

        for (DispatchTaskDTO dispatchTaskDto : dispatchTaskList) {
            BaseDispatchTask baseDispatchTask = new BaseDispatchTask();
            baseDispatchTask.setTaskId(dispatchTaskDto.getTaskId());
            baseDispatchTask.setTaskNo(dispatchTaskDto.getTaskNo());
            baseDispatchTask.setWorkOrderProcessId(dispatchTaskDto.getWorkOrderProcessId());
            baseDispatchTask.setWorkOrderNo(dispatchTaskDto.getWorkOrderNo());
            baseDispatchTask.setWorkCenterId(dispatchTaskDto.getWorkCenterId());
            baseDispatchTask.setWorkCenterCode(dispatchTaskDto.getWorkCenterCode());
            baseDispatchTask.setWorkCenterName(dispatchTaskDto.getWorkCenterName());
            baseDispatchTask.setProcessId(dispatchTaskDto.getProcessId());
            baseDispatchTask.setProcessName(dispatchTaskDto.getProcessName());
            baseDispatchTask.setProcessCode(dispatchTaskDto.getProcessCode());
            baseDispatchTask.setMaterialId(dispatchTaskDto.getMaterialId());
            baseDispatchTask.setMaterialCode(dispatchTaskDto.getMaterialCode());
            baseDispatchTask.setMaterialName(dispatchTaskDto.getMaterialName());
            baseDispatchTask.setPlanStartTime(dispatchTaskDto.getPlanStartTime());
            baseDispatchTask.setPlanEndTime(dispatchTaskDto.getPlanEndTime());
            baseDispatchTask.setDispatchQty(new BigDecimal(dispatchTaskDto.getDispatchQty()));
            baseDispatchTask.setOrderId(productionPlanDTO.getOrderId());
            if (dispatchTaskDto.getId()==null) {
                baseDispatchTask.setCreateTime(new Date());
                baseDispatchTask.setCreatedAt(new Date());
                baseDispatchTask.setTaskPlanStatus(0);
                baseDispatchTask.setTaskStatus(MesTaskStatusEnum.NO_STARTED.getName());
                baseDispatchTaskService.save(baseDispatchTask);
            }else {
                baseDispatchTask.setUpdateTime(new Date());
                baseDispatchTask.setUpdateBy(SecurityUtils.getLoginUser().getUser().getUserName());
                baseDispatchTask.setId(Long.valueOf(dispatchTaskDto.getId()));
                baseDispatchTaskService.updateById(baseDispatchTask);
            }
            ArrayList<BaseDeliveryInfoDTO> deliveryInfoList = dispatchTaskDto.getDeliveryInfo();
            for (BaseDeliveryInfoDTO deliveryInfo : deliveryInfoList) {
                BaseDeliveryInfo baseDeliveryInfo = new BaseDeliveryInfo();
                baseDeliveryInfo.setTaskId(dispatchTaskDto.getTaskId());
                baseDeliveryInfo.setPreparationNo(deliveryInfo.getPreparationNo());
                baseDeliveryInfo.setMaterialId(deliveryInfo.getMaterialId());
                baseDeliveryInfo.setMaterialCode(deliveryInfo.getMaterialCode());
                baseDeliveryInfo.setMaterialName(deliveryInfo.getMaterialName());
                baseDeliveryInfo.setMaterialSpec(deliveryInfo.getMaterialSpec());
                baseDeliveryInfo.setMaterialModel(deliveryInfo.getMaterialModel());
                baseDeliveryInfo.setMaterialDesc(deliveryInfo.getMaterialDesc());
                baseDeliveryInfo.setProcessId(deliveryInfo.getProcessId());
                baseDeliveryInfo.setProcessName(deliveryInfo.getProcessName());
                baseDeliveryInfo.setProcessCode(deliveryInfo.getProcessCode());
                baseDeliveryInfo.setWorkCenterCode(deliveryInfo.getWorkCenterCode());
                baseDeliveryInfo.setWorkCenterName(deliveryInfo.getWorkCenterName());
                baseDeliveryInfo.setWorkCenterId(deliveryInfo.getWorkCenterId());
                baseDeliveryInfo.setRequiredQty(new BigDecimal(deliveryInfo.getRequiredQty()));
                baseDeliveryInfo.setPlanTime(deliveryInfo.getPlanTime());
                baseDeliveryInfo.setBatchNo(deliveryInfo.getBatchNo());
                baseDeliveryInfo.setSerialNo(deliveryInfo.getSerialNo());
                baseDeliveryInfo.setDeliveryPosId(deliveryInfo.getDeliveryPosId());
                baseDeliveryInfo.setDeliveryPosName(deliveryInfo.getDeliveryPosName());
                baseDeliveryInfo.setDeliveryPosCode(deliveryInfo.getDeliveryPosCode());
                baseDeliveryInfo.setIsDelete(false);
                if (deliveryInfo.getId()==null) {
                    baseDeliveryInfoService.save(baseDeliveryInfo);
                }else {
                    baseDeliveryInfo.setId(Long.valueOf(deliveryInfo.getId()));
                    baseDeliveryInfoService.updateById(baseDeliveryInfo);
                }
            }
        }
        return "";
    }

    @Override
    public AjaxResult getById(Long id) {
        BaseDispatchTask taskServiceById = baseDispatchTaskService.getById(id);
        BaseWorkOrder order = baseWorkOrderService.getOne(new LambdaQueryWrapper<BaseWorkOrder>().eq(BaseWorkOrder::getOrderId, taskServiceById.getOrderId()));
        List<BaseDispatchTask> list = baseDispatchTaskService.list(new LambdaQueryWrapper<BaseDispatchTask>().eq(BaseDispatchTask::getOrderId, order.getOrderId()));
        ArrayList<DispatchTaskDTO> taskDTOList = new ArrayList<>();
        for (BaseDispatchTask baseDispatchTask : list) {
            DispatchTaskDTO dispatchTaskDTO = new DispatchTaskDTO();
            dispatchTaskDTO.setTaskId(baseDispatchTask.getTaskId());
            dispatchTaskDTO.setTaskNo(baseDispatchTask.getTaskNo());
            dispatchTaskDTO.setWorkOrderProcessId(baseDispatchTask.getWorkOrderProcessId());
            dispatchTaskDTO.setWorkOrderNo(baseDispatchTask.getWorkOrderNo());
            dispatchTaskDTO.setWorkCenterId(baseDispatchTask.getWorkCenterId());
            dispatchTaskDTO.setWorkCenterCode(baseDispatchTask.getWorkCenterCode());
            dispatchTaskDTO.setWorkCenterName(baseDispatchTask.getWorkCenterName());
            dispatchTaskDTO.setProcessId(baseDispatchTask.getProcessId());
            dispatchTaskDTO.setProcessName(baseDispatchTask.getProcessName());
            dispatchTaskDTO.setProcessCode(baseDispatchTask.getProcessCode());
            dispatchTaskDTO.setMaterialId(baseDispatchTask.getMaterialId());
            dispatchTaskDTO.setMaterialCode(baseDispatchTask.getMaterialCode());
            dispatchTaskDTO.setMaterialName(baseDispatchTask.getMaterialName());
            dispatchTaskDTO.setPlanStartTime(baseDispatchTask.getPlanStartTime());
            dispatchTaskDTO.setPlanEndTime(baseDispatchTask.getPlanEndTime());
            dispatchTaskDTO.setDispatchQty(baseDispatchTask.getDispatchQty().toPlainString());
            dispatchTaskDTO.setId(baseDispatchTask.getId().toString());
            ArrayList<BaseDeliveryInfoDTO> deliveryInfoDTOList = new ArrayList<>();
            List<BaseDeliveryInfo> deliveryInfoList = baseDeliveryInfoService.list(new LambdaQueryWrapper<BaseDeliveryInfo>().eq(BaseDeliveryInfo::getTaskId, baseDispatchTask.getTaskId()));
            for (BaseDeliveryInfo baseDeliveryInfo : deliveryInfoList) {
                BaseDeliveryInfoDTO baseDeliveryInfoDTO = new BaseDeliveryInfoDTO();
                baseDeliveryInfoDTO.setPreparationNo(baseDeliveryInfo.getPreparationNo());
                baseDeliveryInfoDTO.setMaterialId(baseDeliveryInfo.getMaterialId());
                baseDeliveryInfoDTO.setMaterialCode(baseDeliveryInfo.getMaterialCode());
                baseDeliveryInfoDTO.setMaterialName(baseDeliveryInfo.getMaterialName());
                baseDeliveryInfoDTO.setMaterialSpec(baseDeliveryInfo.getMaterialSpec());
                baseDeliveryInfoDTO.setId(baseDeliveryInfo.getId().toString());
                baseDeliveryInfoDTO.setMaterialModel(baseDeliveryInfo.getMaterialModel());
                baseDeliveryInfoDTO.setMaterialDesc(baseDeliveryInfo.getMaterialDesc());
                baseDeliveryInfoDTO.setProcessId(baseDeliveryInfo.getProcessId());
                baseDeliveryInfoDTO.setProcessName(baseDeliveryInfo.getProcessName());
                baseDeliveryInfoDTO.setProcessCode(baseDeliveryInfo.getProcessCode());
                baseDeliveryInfoDTO.setWorkCenterCode(baseDeliveryInfo.getWorkCenterCode());
                baseDeliveryInfoDTO.setWorkCenterName(baseDeliveryInfo.getWorkCenterName());
                baseDeliveryInfoDTO.setWorkCenterId(baseDeliveryInfo.getWorkCenterId());
                baseDeliveryInfoDTO.setRequiredQty(baseDeliveryInfo.getRequiredQty().toString());
                baseDeliveryInfoDTO.setPlanTime(baseDeliveryInfo.getPlanTime());
                baseDeliveryInfoDTO.setBatchNo(baseDeliveryInfo.getBatchNo());
                baseDeliveryInfoDTO.setSerialNo(baseDeliveryInfo.getSerialNo());
                baseDeliveryInfoDTO.setDeliveryPosId(baseDeliveryInfo.getDeliveryPosId());
                baseDeliveryInfoDTO.setDeliveryPosName(baseDeliveryInfo.getDeliveryPosName());
                baseDeliveryInfoDTO.setDeliveryPosCode(baseDeliveryInfo.getDeliveryPosCode());
                deliveryInfoDTOList.add(baseDeliveryInfoDTO);
            }
            dispatchTaskDTO.setDeliveryInfo(deliveryInfoDTOList);
            taskDTOList.add(dispatchTaskDTO);
        }
        ProductionPlanDTO productionPlanDTO = new ProductionPlanDTO();
        productionPlanDTO.setOrderNo(order.getOrderNo());
        productionPlanDTO.setMaterialId(order.getMaterialId());
        productionPlanDTO.setMaterialCode(order.getMaterialCode());
        productionPlanDTO.setMaterialName(order.getMaterialName());
        productionPlanDTO.setMaterialSpec(order.getMaterialSpec());
        productionPlanDTO.setMaterialModel(order.getMaterialModel());
        productionPlanDTO.setOrderId(order.getOrderId());
        productionPlanDTO.setDispatchTask(taskDTOList);
        productionPlanDTO.setId(order.getId().toString());
        return AjaxResult.success(productionPlanDTO);
    }
}
